import 'dart:async';
import 'dart:io';

import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:get/get.dart';
import 'package:in_app_purchase/in_app_purchase.dart';
import 'package:in_app_purchase_storekit/in_app_purchase_storekit.dart';
import 'package:in_app_purchase_storekit/store_kit_wrappers.dart';

import '../dd_module/dd_personal_center/controllers/dd_coin_shop_controller.dart';
import 'dd_http.dart';
import 'dd_log_service.dart';
import 'dd_user_service.dart';

class DDIosPayService extends GetxService{
  List<String> _kProductIds = <String>[];

  List<ProductDetails> _products = <ProductDetails>[];

  late StreamSubscription<List<PurchaseDetails>> _subscription;

  String orderID = "";

  @override
  void onInit() {
    super.onInit();
    _subscription = InAppPurchase.instance.purchaseStream.listen(
            (List<PurchaseDetails> purchaseDetailsList) {
          _listenToPurchaseUpdated(purchaseDetailsList);
        }, onDone: () {
      _subscription.cancel();
    }, onError: (Object error) {
      // handle error here.
    });
  }

  Future<void> applePay(Map dataMap) async {
    final bool isAvailable = await InAppPurchase.instance.isAvailable();
    if (!isAvailable) {
      EasyLoading.dismiss();
      EasyLoading.showToast("Invalid purchase");
      return;
    }

    if (Platform.isIOS) {
      var iosPlatformAddition = InAppPurchase.instance
          .getPlatformAddition<InAppPurchaseStoreKitPlatformAddition>();
      await iosPlatformAddition.setDelegate(ExamplePaymentQueueDelegate());
    }

    if (dataMap['goodsCode'] == null) {
      EasyLoading.dismiss();
      EasyLoading.showToast("No product");
      return;
    }
    _kProductIds.add(dataMap['goodsCode']);

    final ProductDetailsResponse productDetailResponse =
    await InAppPurchase.instance.queryProductDetails(_kProductIds.toSet());

    if (productDetailResponse.error != null) {
      EasyLoading.dismiss();
      EasyLoading.showToast("Failed to product information");
      return;
    }

    if (productDetailResponse.productDetails.isEmpty) {
      EasyLoading.dismiss();
      EasyLoading.showToast("No product");
      return;
    }
    _products = productDetailResponse.productDetails;

    ProductDetails productDetails = _products[0];
    orderID = dataMap['orderNo'];
    late PurchaseParam purchaseParam;
    purchaseParam = PurchaseParam(
        productDetails: productDetails,
        applicationUserName: '${dataMap['orderNo']}');
    InAppPurchase.instance.buyConsumable(purchaseParam: purchaseParam);
  }

  Future<void> _listenToPurchaseUpdated(
      List<PurchaseDetails> purchaseDetailsList) async {
    for (final PurchaseDetails purchaseDetails in purchaseDetailsList) {
      if (purchaseDetails.status == PurchaseStatus.pending) {
        print(purchaseDetails.status);
      } else if (purchaseDetails.status == PurchaseStatus.canceled) {
        InAppPurchase.instance.completePurchase(purchaseDetails);
        EasyLoading.dismiss();
      } else {
        if (purchaseDetails.status == PurchaseStatus.error) {
          EasyLoading.dismiss();
          EasyLoading.showToast("Purchase error");
          InAppPurchase.instance.completePurchase(purchaseDetails);
        } else if (purchaseDetails.status == PurchaseStatus.purchased ||
            purchaseDetails.status == PurchaseStatus.restored) {
          await deliverProduct(purchaseDetails);
        }
      }
    }
  }


  Future<void> createOrder(String orderPrchase, String payChannel) async {

   _kProductIds = <String>[];
    _products = <ProductDetails>[];
    orderID = "";

    DDLogService().ddGa(page: "createorder");
    EasyLoading.show();
    Map<String, dynamic>? result = await rechargeCreate(orderPrchase, payChannel);
    if (null != result && result["code"] ==0 && result['data'] != null) {
      Map<String, dynamic> data = result['data'];
      applePay(data);
    } else {
      EasyLoading.dismiss();
      EasyLoading.showToast("Order creation failed");
    }
  }

  Future<void> deliverProduct(PurchaseDetails purchaseDetails) async {
    EasyLoading.show(maskType: EasyLoadingMaskType.black);
    Map<String, dynamic>? result = await paymentIpa(orderID, purchaseDetails.verificationData.serverVerificationData,purchaseDetails.purchaseID ??'');
    await EasyLoading.dismiss();
    InAppPurchase.instance.completePurchase(purchaseDetails);
    if (null != result && result["code"] ==0) {
      await Get.find<DDUserService>().reloadUserCoins();
    } else {
      String errorMessage = '';
      if(result != null &&  result["code"] != null){
        errorMessage = result["code"];
      }
      await EasyLoading.showToast("Server verification failed${errorMessage}",duration: Duration(seconds: 2));
      await EasyLoading.showToast("Product delivery failed");
    }
  }

  @override
  void onClose() {
    super.onClose();
    if (Platform.isIOS) {
      final InAppPurchaseStoreKitPlatformAddition iosPlatformAddition =
      InAppPurchase.instance
          .getPlatformAddition<InAppPurchaseStoreKitPlatformAddition>();
      iosPlatformAddition.setDelegate(null);
    }
    _subscription.cancel();
  }
}

class ExamplePaymentQueueDelegate implements SKPaymentQueueDelegateWrapper {
  @override
  bool shouldContinueTransaction(
      SKPaymentTransactionWrapper transaction, SKStorefrontWrapper storefront) {
    return true;
  }

  @override
  bool shouldShowPriceConsent() {
    return false;
  }
}
